package Controller

import (
	"back_go/DAO"
	models "back_go/DAO/model"
	middleware "back_go/Middleware"
	"back_go/Response"
	"context"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/minio/minio-go/v7"
	"math"
	"net/http"
	"regexp"
	"strconv"
	"time"
)

type IndexImgParam struct {
	ImgID      uint64    ` json:"imgId,omitempty"`
	ShopID     uint64    `json:"shopId,omitempty"`
	ImgUrl     string    ` json:"imgUrl,omitempty"`
	Des        string    ` json:"des"`
	Title      string    ` json:"title"`
	Link       string    `json:"link"`
	Status     int8      `json:"status,omitempty"`
	Seq        int       ` json:"seq"`
	UploadTime time.Time ` json:"uploadTime,omitempty"`
	Relation   uint64    ` json:"relation,omitempty"`
	Type       int       `json:"type"`
	Pic        string    `json:"pic,omitempty"`
	ProdName   string    `json:"prodName,omitempty"`
}

// GetIndexImg 获取轮播图
/*
参数:
	current: 当前页
	size: 每页大小
	status: 状态
	@Summary 获取轮播图
	@return 轮播图列表
*/
func GetIndexImg(c *gin.Context) {
	var engine = DAO.Engine
	var indexImgs []models.TzIndexImg
	var indexImg models.TzIndexImg
	currentStr := c.Query("current")
	sizeStr := c.Query("size")
	status := c.Query("status")

	page, err := strconv.Atoi(currentStr)
	if err != nil || page < 1 {
		page = 1
	}

	size, err := strconv.Atoi(sizeStr)
	if err != nil || size < 1 {
		size = 10
	}

	var count int64
	if status == "" {
		offset := (page - 1) * size
		err = engine.Limit(size, offset).Find(&indexImgs)
		count, _ = engine.Count(&indexImg)
		if err != nil || count == 0 {
			// 空记录返回
			emptyData := Response.ResponseBody{
				Code: "00000",
				Msg:  nil,
				Data: PageParam1[models.TzIndexImg]{
					Current: page,
					Total:   0,
					Size:    size,
					Records: []models.TzIndexImg{},
					Pages:   0,
				},
				Version:   "V1.0",
				Timestamp: time.Now().Unix(),
				Sign:      "",
				Success:   true,
				Fail:      false,
			}
			c.JSON(200, emptyData)
			return
		}
	}
	if status != "" {
		statusInt, _ := strconv.ParseInt(status, 10, 8)
		err = engine.Where("status =?", statusInt).Limit(size, (page-1)*size).Find(&indexImgs)
		count, err = engine.Where("status =?", statusInt).Count(&indexImg)
		if err != nil || count == 0 {
			// 空记录返回
			emptyData := Response.ResponseBody{
				Code: "00000",
				Msg:  nil,
				Data: PageParam1[models.TzIndexImg]{
					Current: page,
					Total:   0,
					Size:    size,
					Records: []models.TzIndexImg{},
					Pages:   0,
				},
				Version:   "V1.0",
				Timestamp: time.Now().Unix(),
				Sign:      "",
				Success:   true,
				Fail:      false,
			}
			c.JSON(200, emptyData)
			return
		}
	}

	responseData := Response.ResponseBody{
		Code: "00000",
		Msg:  nil,
		Data: PageParam1[models.TzIndexImg]{
			Current: page,
			Total:   count,
			Size:    size,
			Records: indexImgs,
			Pages:   int(math.Ceil(float64(count) / float64(size))),
		},
		Version:   "V1.0",
		Timestamp: time.Now().Unix(),
		Sign:      "",
		Success:   true,
		Fail:      false,
	}
	c.JSON(200, responseData)
}

// GetIndexImgById 根据id获取轮播图
/*
参数:
	imgId: 图片id
	@Summary 根据id获取轮播图
	@return 轮播图
*/
func GetIndexImgById(c *gin.Context) {
	var engine = DAO.Engine
	var indexImg models.TzIndexImg
	var indexImgParam IndexImgParam
	var prod models.TzProd
	imgId := c.Param("imgId")
	_, err := engine.Where("img_id =?", imgId).Get(&indexImg)
	indexImgParam.ImgID = indexImg.ImgID
	indexImgParam.ShopID = indexImg.ShopID
	indexImgParam.ImgUrl = indexImg.ImgUrl
	indexImgParam.Des = indexImg.Des
	indexImgParam.Title = indexImg.Title
	if indexImg.Link != "" {
		indexImgParam.Link = indexImg.Link
	}
	indexImgParam.Status = indexImg.Status

	indexImgParam.Seq = indexImg.Seq
	indexImgParam.UploadTime = indexImg.UploadTime
	indexImgParam.Relation = indexImg.Relation
	indexImgParam.Type = indexImg.Type

	// 根据 indexImg.Relation 查询 prod 的 pic 和 prod_name

	_, err = engine.Where("prod_id = ?", indexImg.Relation).Cols("pic,prod_name").Get(&prod)
	indexImgParam.Pic = "https://img.mall4j.com/" + prod.Pic
	indexImgParam.ProdName = prod.ProdName

	if err != nil {
		c.JSON(http.StatusOK, Response.ResponseBody{
			Code:      "A00005",
			Msg:       "服务器出了点小问题",
			Data:      nil,
			Version:   "v1.0",
			Sign:      nil,
			Success:   false,
			Fail:      true,
			Timestamp: time.Now().Unix(),
		})
		return
	}
	c.JSON(http.StatusOK, Response.ResponseBody{
		Code:      "00000",
		Msg:       nil,
		Data:      indexImgParam,
		Version:   "v1.0",
		Sign:      nil,
		Success:   true,
		Fail:      false,
		Timestamp: time.Now().Unix(),
	})
}

//	SaveIndexImg 保存轮播图
/*
参数:
	indexImgParam: 轮播图参数
	@Summary 保存轮播图
	@return 轮播图
*/
func SaveIndexImg(c *gin.Context) {
	var engine = DAO.Engine
	var indexImgParam IndexImgParam
	err := c.ShouldBindJSON(&indexImgParam)
	if err != nil {
		fmt.Println(err)
		c.JSON(http.StatusOK, Response.ResponseBody{
			Code:      "A00005",
			Msg:       "参数错误",
			Data:      nil,
			Version:   "v1.0",
			Sign:      nil,
			Success:   false,
			Fail:      true,
			Timestamp: time.Now().Unix(),
		})
		return
	}

	var indexImg models.TzIndexImg
	indexImg.ImgID = indexImgParam.ImgID
	indexImg.ShopID = indexImgParam.ShopID
	indexImg.ImgUrl = indexImgParam.ImgUrl
	indexImg.Des = indexImgParam.Des
	indexImg.Title = indexImgParam.Title
	indexImg.Link = indexImgParam.Link
	indexImg.Status = indexImgParam.Status
	indexImg.UploadTime = time.Now()
	indexImg.Relation = indexImgParam.Relation
	indexImg.Type = indexImgParam.Type
	indexImg.Seq = indexImgParam.Seq

	_, err = engine.Insert(&indexImg)

	c.JSON(http.StatusOK, Response.ResponseBody{
		Code:      "00000",
		Msg:       nil,
		Data:      nil,
		Version:   "v1.0",
		Sign:      nil,
		Success:   true,
		Fail:      false,
		Timestamp: time.Now().Unix(),
	})
}

//	DeleteIndexImg 删除轮播图
/*
参数:
	ImgId: 图片id
	@Summary 删除轮播图
	 @return 无
*/
func DetIndexImg(c *gin.Context) {
	var engine = DAO.Engine
	var ImgId []int
	err := c.ShouldBindJSON(&ImgId)
	if err != nil {
		c.JSON(http.StatusOK, Response.ResponseBody{
			Code:      "A00005",
			Msg:       "参数错误",
			Data:      nil,
			Version:   "v1.0",
			Sign:      nil,
			Success:   false,
			Fail:      true,
			Timestamp: time.Now().Unix(),
		})
		return
	}

	// 获取要删除的图片记录
	var imgRecords []models.TzIndexImg
	err = engine.In("img_id", ImgId).Find(&imgRecords)
	if err != nil {
		c.JSON(http.StatusOK, Response.ResponseBody{
			Code:    "A00005",
			Msg:     "服务器出了点小问题",
			Data:    nil,
			Version: "v1.0",
			Sign:    nil,
			Success: false,
			Fail:    true,
		})
		return
	}

	// 删除 MinIO 中的文件
	for _, imgRecord := range imgRecords {
		re := regexp.MustCompile(`([a-zA-Z0-9-]+\.jpg)`)
		matches := re.FindAllStringSubmatch(imgRecord.ImgUrl, -1)
		for _, match := range matches {
			if len(match) > 1 {
				filename := match[1]
				err := middleware.MinioClient.RemoveObject(context.Background(), "indeximg", filename, minio.RemoveObjectOptions{})
				cacheKey := "cache/" + filename
				_ = middleware.RedisClient.Del(c, cacheKey)
				if err != nil {
					// 处理删除失败的情况
					// 可以选择记录错误日志或者返回错误信息给调用方
				}
			}
		}
	}
	// 删除数据库记录
	_, err = engine.In("img_id", ImgId).Delete(&models.TzIndexImg{})
	if err != nil {
		c.JSON(http.StatusOK, Response.ResponseBody{
			Code:    "A00005",
			Msg:     "服务器出了点小问题",
			Data:    nil,
			Version: "v1.0",
			Sign:    nil,
			Success: false,
			Fail:    true,
		})
		return
	}
	c.JSON(http.StatusOK, Response.ResponseBody{
		Code:      "00000",
		Msg:       nil,
		Data:      nil,
		Version:   "v1.0",
		Sign:      nil,
		Success:   true,
		Fail:      false,
		Timestamp: time.Now().Unix(),
	})
}

//	UpdateIndexImg 更新轮播图
/*
参数:
	indexImgParam: 轮播图参数
	@Summary 更新轮播图
	@return 轮播图
*/
func UpdateIndexImg(c *gin.Context) {
	var engine = DAO.Engine
	var indexImgParam IndexImgParam
	err := c.ShouldBindJSON(&indexImgParam)
	if err != nil {
		fmt.Println(err)
		c.JSON(http.StatusOK, Response.ResponseBody{
			Code:      "A00005",
			Msg:       "参数错误",
			Data:      nil,
			Version:   "v1.0",
			Sign:      nil,
			Success:   false,
			Fail:      true,
			Timestamp: time.Now().Unix(),
		})
		return
	}

	var indexImg models.TzIndexImg

	indexImg.ShopID = indexImgParam.ShopID
	indexImg.ImgUrl = indexImgParam.ImgUrl
	indexImg.Des = indexImgParam.Des
	indexImg.Title = indexImgParam.Title
	indexImg.Link = indexImgParam.Link
	indexImg.Status = indexImgParam.Status
	indexImg.UploadTime = time.Now()
	indexImg.Relation = indexImgParam.Relation
	indexImg.Type = indexImgParam.Type
	indexImg.Seq = indexImgParam.Seq
	indexImg.ImgID = indexImgParam.ImgID
	//先去minio删除旧的图片
	var imgRecords []models.TzIndexImg
	err = engine.In("img_id", indexImg.ImgID).Find(&imgRecords)
	// 删除 MinIO 中的文件
	for _, imgRecord := range imgRecords {
		re := regexp.MustCompile(`([a-zA-Z0-9-]+\.jpg)`)
		matches := re.FindAllStringSubmatch(imgRecord.ImgUrl, -1)
		for _, match := range matches {
			if len(match) > 1 {
				filename := match[1]
				err := middleware.MinioClient.RemoveObject(context.Background(), "indeximg", filename, minio.RemoveObjectOptions{})
				cacheKey := "cache/" + filename
				_ = middleware.RedisClient.Del(c, cacheKey)
				if err != nil {
					// 处理删除失败的情况
					// 可以选择记录错误日志或者返回错误信息给调用方
				}
			}
		}
	}
	_, err = engine.ID(indexImg.ImgID).Update(&indexImg)
	if err != nil {
		fmt.Println(err)
		c.JSON(http.StatusOK, Response.ResponseBody{
			Code:      "A00005",
			Msg:       "服务器出了点小问题",
			Data:      nil,
			Version:   "v1.0",
			Sign:      nil,
			Success:   false,
			Fail:      true,
			Timestamp: time.Now().Unix(),
		})
		return
	}
	c.JSON(http.StatusOK, Response.ResponseBody{
		Code:      "00000",
		Msg:       nil,
		Data:      nil,
		Version:   "v1.0",
		Sign:      nil,
		Success:   true,
		Fail:      false,
		Timestamp: time.Now().Unix(),
	})
}
